<template>
  <!-- 故障归属分析 -->
  <a-spin :spinning="loading">
    <div class="failureAttribution" ref="containerRef">
      <div class="titleBar">
        <div class="title">
          故障归属分析
          <div class="dateRange">
            <a-range-picker
              v-model:value="dateRange"
              size="small"
              :allowClear="false"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              style="margin-right: 8px"
            />
            <a-button
              size="small"
              type="primary"
              class="queryBtn"
              @click="outageDashboardData"
              >查询</a-button
            >
            <a-button size="small" type="link" @click="handleReset"
              >重置</a-button
            >
          </div>
        </div>
      </div>
      <div class="content">
        <div class="topCharts">
          <div class="pieChartContainer">
            <div class="chartTitle">故障归属损失占比</div>
            <div ref="pieChartRef" class="chartContainer"></div>
          </div>
          <div class="barChartContainer">
            <div class="chartTitle">故障归属等数损失收益</div>
            <div ref="barChartRef" class="chartContainer"></div>
          </div>
        </div>
        <div class="tableContainer" :style="{ width: containerWidth + 'px' }">
          <a-table
            :columns="columns"
            :data-source="tableData"
            :pagination="false"
            size="small"
            :scroll="{ x: 1120, y: 140 }"
          >
            <template #bodyCell="{ column, index }">
              <template v-if="column.key === 'index'">
                {{ index + 1 }}
              </template>
            </template>
          </a-table>
        </div>
      </div>
    </div>
  </a-spin>
</template>

<script setup>

import * as echarts from "echarts";
import dayjs from "dayjs";
const props = defineProps({
  pageType: {
    type: String,
  },
});
const $api = inject("$api");
const getDefaultDateRange = () => {
  // 默认选上月的1号到上月的最后一天
  const end = dayjs().subtract(1, "month").endOf("month");
  const start = dayjs().subtract(1, "month").startOf("month");
  return [start.format("YYYY-MM-DD"), end.format("YYYY-MM-DD")];
};
const dateRange = ref(getDefaultDateRange());
const pieChartRef = ref(null);
const barChartRef = ref(null);
let pieChart = null;
let barChart = null;
const chartData = ref([]);
const columns = [
  {
    title: "序号",
    dataIndex: "index",
    key: "index",
    width: 60,
    align: "center",
    ellipsis: true,
  },
  {
    title: "电站名称",
    dataIndex: "stationName",
    key: "stationName",
    width: 120,
    ellipsis: true,
  },
  {
    title: "所属厂商",
    dataIndex: "supplierName",
    key: "supplierName",
    width: 100,
    ellipsis: true,
  },
  {
    title: "故障现象描述",
    dataIndex: "faultDesc",
    key: "faultDesc",
    width: 220,
    ellipsis: true,
  },
  {
    title: "缺陷及故障处理方法描述",
    dataIndex: "faultDealDesc",
    key: "faultDealDesc",
    width: 300,
    ellipsis: true,
  },
  {
    title: "故障类别",
    dataIndex: "faultTypeName",
    key: "faultTypeName",
    width: 120,
  },
  {
    title: "故障细分",
    dataIndex: "faultSegmentName",
    key: "faultSegmentName",
    width: 120,
  },
  {
    title: "故障归属",
    dataIndex: "faultBelongName",
    key: "faultBelongName",
    width: 120,
  },
  {
    title: "故障开始时间",
    dataIndex: "faultStartDate",
    key: "faultStartDate",
    width: 160,
  },
  {
    title: "停运时长",
    dataIndex: "faultFixTime",
    key: "faultFixTime",
    width: 80,
  },
  {
    title: "故障修复时间（小时）",
    dataIndex: "faultFixTime",
    key: "faultFixTime",
    width: 140,
  },
];

const tableData = ref([
  {
    key: "1",
    stationName: "新巨能",
    description:
      "为SD卡无法写入数据，导致程序卡住，物联部系统性重启后恢复正常运行",
    category: "硬件故障",
    subCategory: "电表",
    attribution: "物联部",
    startTime: "2025-03-26 21:20:00",
    downtime: "24.3",
    repairTime: "136.7",
  },
  {
    key: "2",
    stationName: "新巨能",
    description:
      "企业侧侧断电，当时储能处于静默的段，厂区将并网柜分闸，工程部同事现场处理后恢复正常运行",
    category: "硬件故障",
    subCategory: "企业断电",
    attribution: "用户",
    startTime: "2025-03-26 07:58:00",
    downtime: "是",
    repairTime: "195.6",
  },
  {
    key: "1",
    stationName: "新巨能",
    description:
      "为SD卡无法写入数据，导致程序卡住，物联部系统性重启后恢复正常运行",
    category: "硬件故障",
    subCategory: "电表",
    attribution: "物联部",
    startTime: "2025-03-26 21:20:00",
    downtime: "24.3",
    repairTime: "136.7",
  },
  {
    key: "2",
    stationName: "新巨能",
    description:
      "企业侧侧断电，当时储能处于静默的段，厂区将并网柜分闸，工程部同事现场处理后恢复正常运行",
    category: "硬件故障",
    subCategory: "企业断电",
    attribution: "用户",
    startTime: "2025-03-26 07:58:00",
    downtime: "是",
    repairTime: "195.6",
  },
  {
    key: "1",
    description:
      "为SD卡无法写入数据，导致程序卡住，物联部系统性重启后恢复正常运行",
    category: "硬件故障",
    subCategory: "电表",
    attribution: "物联部",
    startTime: "2025-03-26 21:20:00",
    downtime: "24.3",
    repairTime: "136.7",
  },
  {
    key: "2",
    description:
      "企业侧侧断电，当时储能处于静默的段，厂区将并网柜分闸，工程部同事现场处理后恢复正常运行",
    category: "硬件故障",
    subCategory: "企业断电",
    attribution: "用户",
    startTime: "2025-03-26 07:58:00",
    downtime: "是",
    repairTime: "195.6",
  },
]);
const selectedPieIndex = ref(-1); // 饼图选中
const selectedBarIndex = ref(-1); // 柱状图选中

// 处理图表点击事件，更新表格数据
const handleChartClick = (selectedName) => {
  if (selectedName) {
    // 根据选中的name查找对应的数据
    const selectedData = chartData.value.find(
      (item) => item.faultBelong === selectedName
    );
    if (selectedData && selectedData.faultDealDtoList) {
      tableData.value = selectedData.faultDealDtoList.map((item, index) => ({
        ...item,
        key: index + 1,
      }));
    } else {
      tableData.value = [];
    }
  } else {
    tableData.value = chartData.value.map((item) => item.faultDealDtoList).flat().map((item, index) => ({
      ...item,
      key: index + 1,
    }));
  }
};

const initPieChart = () => {
  if (!pieChartRef.value) return;
  if (pieChart) {
    pieChart.dispose();
  }
  pieChart = echarts.init(pieChartRef.value);

  const legendData = chartData.value.map((item) => item.faultBelong);
  // 检查数据是否存在
  if (legendData.length === 0) {
    const option = {
      title: {
        text: "暂无数据",
        left: "center",
        top: "center",
        textStyle: {
          color: "#94a3b8",
          fontSize: 14,
        },
      },
      backgroundColor: "transparent",
    };
    pieChart.setOption(option);
    return;
  }
  // 定义颜色配置
  const colorConfig = {
    物联部: "#6377ff",
    麦米: "#1890ff",
    工程部: "#13c2c2",
    华致: "#2fc25b",
    英飞源: "#ecc94b",
    奇点: "#ff9f43",
    用户: "#ed64a6",
  };
  // 通用的 label 配置
  const createLabelConfig = (color) => ({
    show: true,
    position: "outside",
    formatter: (params) => {
      return `{name|${params.name}}\n{percent|${params.percent}%}`;
    },
    rich: {
      name: {
        fontSize: 14,
        color: color,
      },
      percent: {
        fontSize: 12,
        fontWeight: "normal",
        color: "#e2e8f0",
        textShadowBlur: 0,
        textShadowColor: "none",
      },
    },
    distanceToLabelLine: 5,
  });

  // 生成 seriesData
  let seriesData = Object.entries(colorConfig)
    .map(([name, color]) => ({
      value: parseFloat(
        chartData.value
          .find((item) => item.faultBelong === name)
          ?.ratio?.replace("%", "") || "0"
      ),
      name,
      itemStyle: { color },
      label: createLabelConfig(color),
    }))
    .filter((item) => legendData.includes(item.name));

  const option = {
    tooltip: {
      trigger: "item",
      formatter: "{b}: {c}%",
      backgroundColor: "rgba(0,0,0,0.7)",
      borderColor: "#334155",
      textStyle: {
        color: "#e2e8f0",
      },
    },
    legend: {
      orient: "vertical",
      right: window.innerWidth <= 1500 ? "0" : "10%",
      top: "center",
      itemWidth: 10,
      itemHeight: 10,
      textStyle: {
        color: "#e2e8f0",
        fontSize: 12,
      },
      formatter: function (name) {
        return name;
      },
      data: legendData,
    },

    series: [
      {
        type: "pie",
        radius: window.innerWidth <= 1500 ? "70%" : "75%",
        center: ["40%", "50%"],
        data: seriesData,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: "rgba(0, 0, 0, 0.5)",
          },
        },
        labelLine: {
          show: true,
          length: 15,
          length2: 10,
          smooth: true,
          lineStyle: {
            width: 1,
            type: "solid",
          },
        },
      },
    ],
  };
  pieChart.setOption(option);

  // 添加点击事件监听
  pieChart.on("click", (params) => {
    // 点击当前选中项取消选中
    if (selectedPieIndex.value === params.dataIndex) {
      selectedPieIndex.value = -1;
      pieChart.dispatchAction({
        type: "downplay",
        seriesIndex: 0,
        dataIndex: params.dataIndex,
      });
      // 取消选中时显示所有数据
      handleChartClick(null);
    } else {
      // 取消之前的高亮
      if (selectedPieIndex.value !== -1) {
        pieChart.dispatchAction({
          type: "downplay",
          seriesIndex: 0,
          dataIndex: selectedPieIndex.value,
        });
      }
      // 设置新的选中项
      selectedPieIndex.value = params.dataIndex;
      pieChart.dispatchAction({
        type: "highlight",
        seriesIndex: 0,
        dataIndex: params.dataIndex,
      });
      // 根据选中的名称更新表格数据
      handleChartClick(params.name);

      // 取消柱状图的选中状态（饼图柱图选中互斥）
      if (selectedBarIndex.value !== -1 && barChart) {
        const barOption = barChart.getOption();
        const barSeriesData = barOption.series[0].data;
        if (
          barSeriesData[selectedBarIndex.value] &&
          barSeriesData[selectedBarIndex.value].itemStyle
        ) {
          barSeriesData[selectedBarIndex.value].itemStyle.color =
            new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: "#5A8DFF" },
              { offset: 1, color: "#2A5FFF" },
            ]);
          barChart.setOption({
            series: [
              {
                data: barSeriesData,
              },
            ],
          });
        }
        selectedBarIndex.value = -1;
      }
    }
  });

  // 默认选中数值最大的扇区
  if (seriesData.length > 0) {
    // 找到数值最大的扇区索引
    let maxIndex = 0;
    let maxValue = seriesData[0].value;

    for (let i = 1; i < seriesData.length; i++) {
      if (seriesData[i].value > maxValue) {
        maxValue = seriesData[i].value;
        maxIndex = i;
      }
    }
    // 设置默认选中
    selectedPieIndex.value = maxIndex;
    pieChart.dispatchAction({
      type: "highlight",
      seriesIndex: 0,
      dataIndex: maxIndex,
    });
    handleChartClick(seriesData[maxIndex].name);
  }
};
const initBarChart = () => {
  if (!barChartRef.value) return;
  if (barChart) {
    barChart.dispose();
  }
  barChart = echarts.init(barChartRef.value);
  const legendData = chartData.value.map((item) => item.faultBelong);
  // 检查数据是否存在
  if (legendData.length === 0) {
    const option = {
      title: {
        text: "暂无数据",
        left: "center",
        top: "center",
        textStyle: {
          color: "#94a3b8",
          fontSize: 14,
        },
      },
      backgroundColor: "transparent",
    };
    barChart.setOption(option);
    return;
  }
  const defaultColor = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
    { offset: 0, color: "#5A8DFF" },
    { offset: 1, color: "#2A5FFF" },
  ]);
  const highlightColor = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
    { offset: 0, color: "#FF9F43" },
    { offset: 1, color: "#FF7A00" },
  ]);
  const seriesData = chartData.value
    .filter((item) => legendData.includes(item.faultBelong))
    .map((item) => ({
      value: item.belongLossProfit,
      itemStyle: {
        color: defaultColor,
        borderRadius: [4, 4, 0, 0],
      },
    }));
  const option = {
    grid: {
      left: "5%",
      right: "5%",
      bottom: "5%",
      top: "5%",
      containLabel: true,
    },
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow",
      },
      backgroundColor: "rgba(0,0,0,0.7)",
      borderColor: "#334155",
      textStyle: {
        color: "#e2e8f0",
      },
    },
    xAxis: {
      type: "category",
      data: legendData,
      axisLine: {
        lineStyle: {
          color: "#475569",
        },
      },
      axisTick: {
        show: false,
      },
      axisLabel: {
        color: "#94a3b8",
        fontSize: 12,
      },
    },
    yAxis: {
      type: "value",
      axisLine: {
        show: false,
      },
      axisTick: {
        show: false,
      },
      axisLabel: {
        color: "#94a3b8",
        fontSize: 12,
      },
      splitLine: {
        lineStyle: {
          color: "#334155",
          type: "dashed",
        },
      },
    },
    series: [
      {
        type: "bar",
        barWidth: 20,
        data: seriesData,
        showBackground: true,
        backgroundStyle: {
          color: "rgba(60, 74, 100, 0.3)",
          borderRadius: [4, 4, 0, 0],
        },
      },
    ],
  };
  barChart.setOption(option);
  barChart.on("click", (params) => {
    const clickedDataIndex = params.dataIndex;
    const currentOption = barChart.getOption();
    const currentSeriesData = currentOption.series[0].data;
    if (selectedBarIndex.value === clickedDataIndex) {
      currentSeriesData[clickedDataIndex].itemStyle.color = defaultColor;
      selectedBarIndex.value = -1;
      // 取消选中时显示所有数据
      handleChartClick(null);
    } else {
      currentSeriesData.forEach((item, index) => {
        if (index === clickedDataIndex) {
          item.itemStyle.color = highlightColor;
        } else {
          item.itemStyle.color = defaultColor;
        }
      });
      selectedBarIndex.value = clickedDataIndex;
      // 根据选中的名称更新表格数据
      handleChartClick(params.name);

      // 取消饼图的选中状态（饼图柱图选中互斥）
      if (selectedPieIndex.value !== -1 && pieChart) {
        pieChart.dispatchAction({
          type: "downplay",
          seriesIndex: 0,
          dataIndex: selectedPieIndex.value,
        });
        selectedPieIndex.value = -1;
      }
    }

    // 更新图表配置
    barChart.setOption({
      series: [
        {
          data: currentSeriesData,
        },
      ],
    });
  });
};

onBeforeUnmount(() => {
  window.removeEventListener("resize", handleResize);
  if (pieChart) {
    pieChart.off("click");
    pieChart.dispose();
  }
  if (barChart) {
    barChart.off("click");
    barChart.dispose();
  }
});
const containerRef = ref(null);
const containerWidth = ref(0);

const updateContainerWidth = () => {
  if (containerRef.value) {
    containerWidth.value = containerRef.value.offsetWidth - 24;
  }
};
const handleReset = () => {
  dateRange.value = getDefaultDateRange();
  chartData.value = [];
  // 重置选中状态
  selectedPieIndex.value = -1;
  selectedBarIndex.value = -1;
  tableData.value = [];
  outageDashboardData();
};
const handleResize = () => {
  pieChart &&
    pieChart.setOption({
      series: [
        {
          radius: window.innerWidth <= 1500 ? "55%" : "70%",
        },
      ],
    });
  barChart && barChart.resize();
  updateContainerWidth();
};
const loading = ref(false);
const outageDashboardData = async () => {
  const params = {
    planShutdown: 0, // 供应链评价这里直接传0
    dashboardStartDate: dateRange.value[0],
    dashboardEndDate: dateRange.value[1],
    dashboardType: "2", // 1：故障类别分析 2：故障归属分析 3：异常趋势分析-年报 4：异常趋势分析-月报
    supplyChainFlag: 1, // 供应链这里特殊传1，给后端标识。其他地方不传
  };
  loading.value = true;
  const res = await $api.faultDealDashboard(2, params);
  loading.value = false;
  if (res?.code === 0 && Object.keys(res.data).length > 0) {
    chartData.value = res.data.faultDealBelongChildDtoList;
  } else {
    chartData.value = [];
    tableData.value = [];
  }
  initPieChart();
  initBarChart();
  updateContainerWidth();
};
onMounted(async () => {
  await outageDashboardData();
  initPieChart();
  initBarChart();
  updateContainerWidth();
  window.addEventListener("resize", handleResize);
});

onBeforeUnmount(() => {
  window.removeEventListener("resize", handleResize);
  pieChart && pieChart.dispose();
  barChart && barChart.dispose();
});
</script>

<style scoped lang="less">
.failureAttribution {
  width: 100%;
  height: 480px;
  padding: 0 12px;
  background: #141414;
  border-radius: 4px;
  border: 1px solid #334155;
  color: #e2e8f0;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  .titleBar {
    flex-shrink: 0;
  }

  .title {
    font-size: 16px;
    font-weight: bold;
    padding: 15px 0;
    border-bottom: 1px solid #334155;
    color: #e2e8f0;
    position: relative;
    flex-shrink: 0;

    .dateRange {
      position: absolute;
      right: 0;
      top: 50%;
      transform: translateY(-50%);
    }
  }

  .content {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    padding: 10px 0;

    .topCharts {
      display: flex;
      height: 220px;

      .pieChartContainer,
      .barChartContainer {
        flex: 1;
        height: 100%;
        position: relative;

        .chartTitle {
          text-align: center;
          font-size: 14px;
          font-weight: bold;
          color: #e2e8f0;
          margin: 8px 0;
        }

        .chartContainer {
          width: 100%;
          height: calc(100% - 25px);
          @media (max-width: 1500px) {
            transform: scale(0.9);
            transform-origin: center center;
          }
        }
      }
    }

    .tableContainer {
      min-width: 0;
      height: 150px;
      margin-top: 10px;

      :deep(.ant-table) {
        width: 100%;
        background: transparent;
        color: #e2e8f0;

        .ant-table-container {
          min-width: 0;
        }

        .ant-table-content {
          overflow-x: auto;
        }

        .ant-table-thead > tr > th {
          background: #1e293b;
          color: #e2e8f0;
          border-bottom: 1px solid #334155;
          padding: 8px 12px;
          font-size: 12px;
          height: 40px;
          line-height: 24px;
        }

        .ant-table-tbody > tr > td {
          border-bottom: 1px solid #334155;
          color: #94a3b8;
          padding: 6px 12px;
          font-size: 12px;
        }

        .ant-table-body {
          overflow-x: auto !important;

          &::-webkit-scrollbar {
            width: 6px;
            height: 6px;
          }

          &::-webkit-scrollbar-thumb {
            background: #475569;
            border-radius: 3px;
          }

          &::-webkit-scrollbar-track {
            background: #1e293b;
          }
        }
      }
    }
  }
}
</style>
